home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / g_cmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  20.2 KB  |  1,067 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. #include "g_local.h"
  21. #include "m_player.h"
  22.  
  23.  
  24. char *ClientTeam (edict_t *ent)
  25. {
  26.     char        *p;
  27.     static char    value[512];
  28.  
  29.     value[0] = 0;
  30.  
  31.     if (!ent->client)
  32.         return value;
  33.  
  34.     strcpy(value, Info_ValueForKey (ent->client->pers.userinfo, "skin"));
  35.     p = strchr(value, '/');
  36.     if (!p)
  37.         return value;
  38.  
  39.     if ((int)(dmflags->value) & DF_MODELTEAMS)
  40.     {
  41.         *p = 0;
  42.         return value;
  43.     }
  44.  
  45.     // if ((int)(dmflags->value) & DF_SKINTEAMS)
  46.     return ++p;
  47. }
  48.  
  49. qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
  50. {
  51.     char    ent1Team [512];
  52.     char    ent2Team [512];
  53.  
  54.     if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
  55.         return false;
  56.  
  57.     strcpy (ent1Team, ClientTeam (ent1));
  58.     strcpy (ent2Team, ClientTeam (ent2));
  59.  
  60.     if (strcmp(ent1Team, ent2Team) == 0)
  61.         return true;
  62.     return false;
  63. }
  64.  
  65.  
  66. void SelectNextItem (edict_t *ent, int itflags)
  67. {
  68.     gclient_t    *cl;
  69.     int            i, index;
  70.     gitem_t        *it;
  71.  
  72.     cl = ent->client;
  73.  
  74. //ZOID
  75.     if (cl->menu) {
  76.         PMenu_Next(ent);
  77.         return;
  78.     } else if (cl->chase_target) {
  79.         ChaseNext(ent);
  80.         return;
  81.     }
  82. //ZOID
  83.  
  84.     // scan  for the next valid one
  85.     for (i=1 ; i<=MAX_ITEMS ; i++)
  86.     {
  87.         index = (cl->pers.selected_item + i)%MAX_ITEMS;
  88.         if (!cl->pers.inventory[index])
  89.             continue;
  90.         it = &itemlist[index];
  91.         if (!it->use)
  92.             continue;
  93.         if (!(it->flags & itflags))
  94.             continue;
  95.  
  96.         cl->pers.selected_item = index;
  97.         return;
  98.     }
  99.  
  100.     cl->pers.selected_item = -1;
  101. }
  102.  
  103. void SelectPrevItem (edict_t *ent, int itflags)
  104. {
  105.     gclient_t    *cl;
  106.     int            i, index;
  107.     gitem_t        *it;
  108.  
  109.     cl = ent->client;
  110.  
  111. //ZOID
  112.     if (cl->menu) {
  113.         PMenu_Prev(ent);
  114.         return;
  115.     } else if (cl->chase_target) {
  116.         ChasePrev(ent);
  117.         return;
  118.     }
  119. //ZOID
  120.  
  121.     // scan  for the next valid one
  122.     for (i=1 ; i<=MAX_ITEMS ; i++)
  123.     {
  124.         index = (cl->pers.selected_item + MAX_ITEMS - i)%MAX_ITEMS;
  125.         if (!cl->pers.inventory[index])
  126.             continue;
  127.         it = &itemlist[index];
  128.         if (!it->use)
  129.             continue;
  130.         if (!(it->flags & itflags))
  131.             continue;
  132.  
  133.         cl->pers.selected_item = index;
  134.         return;
  135.     }
  136.  
  137.     cl->pers.selected_item = -1;
  138. }
  139.  
  140. void ValidateSelectedItem (edict_t *ent)
  141. {
  142.     gclient_t    *cl;
  143.  
  144.     cl = ent->client;
  145.  
  146.     if (cl->pers.inventory[cl->pers.selected_item])
  147.         return;        // valid
  148.  
  149.     SelectNextItem (ent, -1);
  150. }
  151.  
  152.  
  153. //=================================================================================
  154.  
  155. /*
  156. ==================
  157. Cmd_Give_f
  158.  
  159. Give items to a client
  160. ==================
  161. */
  162. void Cmd_Give_f (edict_t *ent)
  163. {
  164.     char        *name;
  165.     gitem_t        *it;
  166.     int            index;
  167.     int            i;
  168.     qboolean    give_all;
  169.     edict_t        *it_ent;
  170.  
  171.     if (deathmatch->value && !sv_cheats->value)
  172.     {
  173.         gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
  174.         return;
  175.     }
  176.  
  177.     name = gi.args();
  178.  
  179.     if (Q_stricmp(name, "all") == 0)
  180.         give_all = true;
  181.     else
  182.         give_all = false;
  183.  
  184.     if (give_all || Q_stricmp(gi.argv(1), "health") == 0)
  185.     {
  186.         if (gi.argc() == 3)
  187.             ent->health = atoi(gi.argv(2));
  188.         else
  189.             ent->health = ent->max_health;
  190.         if (!give_all)
  191.             return;
  192.     }
  193.  
  194.     if (give_all || Q_stricmp(name, "weapons") == 0)
  195.     {
  196.         for (i=0 ; i<game.num_items ; i++)
  197.         {
  198.             it = itemlist + i;
  199.             if (!it->pickup)
  200.                 continue;
  201.             if (!(it->flags & IT_WEAPON))
  202.                 continue;
  203.             ent->client->pers.inventory[i] += 1;
  204.         }
  205.         if (!give_all)
  206.             return;
  207.     }
  208.  
  209.     if (give_all || Q_stricmp(name, "ammo") == 0)
  210.     {
  211.         for (i=0 ; i<game.num_items ; i++)
  212.         {
  213.             it = itemlist + i;
  214.             if (!it->pickup)
  215.                 continue;
  216.             if (!(it->flags & IT_AMMO))
  217.                 continue;
  218.             Add_Ammo (ent, it, 1000);
  219.         }
  220.         if (!give_all)
  221.             return;
  222.     }
  223.  
  224.     if (give_all || Q_stricmp(name, "armor") == 0)
  225.     {
  226.         gitem_armor_t    *info;
  227.  
  228.         it = FindItem("Jacket Armor");
  229.         ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
  230.  
  231.         it = FindItem("Combat Armor");
  232.         ent->client->pers.inventory[ITEM_INDEX(it)] = 0;
  233.  
  234.         it = FindItem("Body Armor");
  235.         info = (gitem_armor_t *)it->info;
  236.         ent->client->pers.inventory[ITEM_INDEX(it)] = info->max_count;
  237.  
  238.         if (!give_all)
  239.             return;
  240.     }
  241.  
  242.     if (give_all || Q_stricmp(name, "Power Shield") == 0)
  243.     {
  244.         it = FindItem("Power Shield");
  245.         it_ent = G_Spawn();
  246.         it_ent->classname = it->classname;
  247.         SpawnItem (it_ent, it);
  248.         Touch_Item (it_ent, ent, NULL, NULL);
  249.         if (it_ent->inuse)
  250.             G_FreeEdict(it_ent);
  251.  
  252.         if (!give_all)
  253.             return;
  254.     }
  255.  
  256.     if (give_all)
  257.     {
  258.         for (i=0 ; i<game.num_items ; i++)
  259.         {
  260.             it = itemlist + i;
  261.             if (!it->pickup)
  262.                 continue;
  263.             if (it->flags & (IT_ARMOR|IT_WEAPON|IT_AMMO))
  264.                 continue;
  265.             ent->client->pers.inventory[i] = 1;
  266.         }
  267.         return;
  268.     }
  269.  
  270.     it = FindItem (name);
  271.     if (!it)
  272.     {
  273.         name = gi.argv(1);
  274.         it = FindItem (name);
  275.         if (!it)
  276.         {
  277.             gi.cprintf (ent, PRINT_HIGH, "unknown item\n");
  278.             return;
  279.         }
  280.     }
  281.  
  282.     if (!it->pickup)
  283.     {
  284.         gi.cprintf (ent, PRINT_HIGH, "non-pickup item\n");
  285.         return;
  286.     }
  287.  
  288.     index = ITEM_INDEX(it);
  289.  
  290.     if (it->flags & IT_AMMO)
  291.     {
  292.         if (gi.argc() == 3)
  293.             ent->client->pers.inventory[index] = atoi(gi.argv(2));
  294.         else
  295.             ent->client->pers.inventory[index] += it->quantity;
  296.     }
  297.     else
  298.     {
  299.         it_ent = G_Spawn();
  300.         it_ent->classname = it->classname;
  301.         SpawnItem (it_ent, it);
  302.         Touch_Item (it_ent, ent, NULL, NULL);
  303.         if (it_ent->inuse)
  304.             G_FreeEdict(it_ent);
  305.     }
  306. }
  307.  
  308.  
  309. /*
  310. ==================
  311. Cmd_God_f
  312.  
  313. Sets client to godmode
  314.  
  315. argv(0) god
  316. ==================
  317. */
  318. void Cmd_God_f (edict_t *ent)
  319. {
  320.     char    *msg;
  321.  
  322.     if (deathmatch->value && !sv_cheats->value)
  323.     {
  324.         gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
  325.         return;
  326.     }
  327.  
  328.     ent->flags ^= FL_GODMODE;
  329.     if (!(ent->flags & FL_GODMODE) )
  330.         msg = "godmode OFF\n";
  331.     else
  332.         msg = "godmode ON\n";
  333.  
  334.     gi.cprintf (ent, PRINT_HIGH, msg);
  335. }
  336.  
  337.  
  338. /*
  339. ==================
  340. Cmd_Notarget_f
  341.  
  342. Sets client to notarget
  343.  
  344. argv(0) notarget
  345. ==================
  346. */
  347. void Cmd_Notarget_f (edict_t *ent)
  348. {
  349.     char    *msg;
  350.  
  351.     if (deathmatch->value && !sv_cheats->value)
  352.     {
  353.         gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
  354.         return;
  355.     }
  356.  
  357.     ent->flags ^= FL_NOTARGET;
  358.     if (!(ent->flags & FL_NOTARGET) )
  359.         msg = "notarget OFF\n";
  360.     else
  361.         msg = "notarget ON\n";
  362.  
  363.     gi.cprintf (ent, PRINT_HIGH, msg);
  364. }
  365.  
  366.  
  367. /*
  368. ==================
  369. Cmd_Noclip_f
  370.  
  371. argv(0) noclip
  372. ==================
  373. */
  374. void Cmd_Noclip_f (edict_t *ent)
  375. {
  376.     char    *msg;
  377.  
  378.     if (deathmatch->value && !sv_cheats->value)
  379.     {
  380.         gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
  381.         return;
  382.     }
  383.  
  384.     if (ent->movetype == MOVETYPE_NOCLIP)
  385.     {
  386.         ent->movetype = MOVETYPE_WALK;
  387.         msg = "noclip OFF\n";
  388.     }
  389.     else
  390.     {
  391.         ent->movetype = MOVETYPE_NOCLIP;
  392.         msg = "noclip ON\n";
  393.     }
  394.  
  395.     gi.cprintf (ent, PRINT_HIGH, msg);
  396. }
  397.  
  398.  
  399. /*
  400. ==================
  401. Cmd_Use_f
  402.  
  403. Use an inventory item
  404. ==================
  405. */
  406. void Cmd_Use_f (edict_t *ent)
  407. {
  408.     int            index;
  409.     gitem_t        *it;
  410.     char        *s;
  411.  
  412.     s = gi.args();
  413.     it = FindItem (s);
  414.     if (!it)
  415.     {
  416.         gi.cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s);
  417.         return;
  418.     }
  419.     if (!it->use)
  420.     {
  421.         gi.cprintf (ent, PRINT_HIGH, "Item is not usable.\n");
  422.         return;
  423.     }
  424.     index = ITEM_INDEX(it);
  425.     if (!ent->client->pers.inventory[index])
  426.     {
  427.         gi.cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s);
  428.         return;
  429.     }
  430.  
  431.     it->use (ent, it);
  432. }
  433.  
  434.  
  435. /*
  436. ==================
  437. Cmd_Drop_f
  438.  
  439. Drop an inventory item
  440. ==================
  441. */
  442. void Cmd_Drop_f (edict_t *ent)
  443. {
  444.     int            index;
  445.     gitem_t        *it;
  446.     char        *s;
  447.  
  448. //ZOID--special case for tech powerups
  449.     if (Q_stricmp(gi.args(), "tech") == 0 && (it = CTFWhat_Tech(ent)) != NULL) {
  450.         it->drop (ent, it);
  451.         return;
  452.     }
  453. //ZOID
  454.  
  455.     s = gi.args();
  456.     it = FindItem (s);
  457.     if (!it)
  458.     {
  459.         gi.cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s);
  460.         return;
  461.     }
  462.     if (!it->drop)
  463.     {
  464.         gi.cprintf (ent, PRINT_HIGH, "Item is not dropable.\n");
  465.         return;
  466.     }
  467.     index = ITEM_INDEX(it);
  468.     if (!ent->client->pers.inventory[index])
  469.     {
  470.         gi.cprintf (ent, PRINT_HIGH, "Out of item: %s\n", s);
  471.         return;
  472.     }
  473.  
  474.     it->drop (ent, it);
  475. }
  476.  
  477.  
  478. /*
  479. =================
  480. Cmd_Inven_f
  481. =================
  482. */
  483. void Cmd_Inven_f (edict_t *ent)
  484. {
  485.     int            i;
  486.     gclient_t    *cl;
  487.  
  488.     cl = ent->client;
  489.  
  490.     cl->showscores = false;
  491.     cl->showhelp = false;
  492.  
  493. //ZOID
  494.     if (ent->client->menu) {
  495.         PMenu_Close(ent);
  496.         ent->client->update_chase = true;
  497.         return;
  498.     }
  499. //ZOID
  500.  
  501.     if (cl->showinventory)
  502.     {
  503.         cl->showinventory = false;
  504.         return;
  505.     }
  506.  
  507. //ZOID
  508.     if (ctf->value && cl->resp.ctf_team == CTF_NOTEAM) {
  509.         CTFOpenJoinMenu(ent);
  510.         return;
  511.     }
  512. //ZOID
  513.  
  514.     cl->showinventory = true;
  515.  
  516.     gi.WriteByte (svc_inventory);
  517.     for (i=0 ; i<MAX_ITEMS ; i++)
  518.     {
  519.         gi.WriteShort (cl->pers.inventory[i]);
  520.     }
  521.     gi.unicast (ent, true);
  522. }
  523.  
  524. /*
  525. =================
  526. Cmd_InvUse_f
  527. =================
  528. */
  529. void Cmd_InvUse_f (edict_t *ent)
  530. {
  531.     gitem_t        *it;
  532.  
  533. //ZOID
  534.     if (ent->client->menu) {
  535.         PMenu_Select(ent);
  536.         return;
  537.     }
  538. //ZOID
  539.  
  540.     ValidateSelectedItem (ent);
  541.  
  542.     if (ent->client->pers.selected_item == -1)
  543.     {
  544.         gi.cprintf (ent, PRINT_HIGH, "No item to use.\n");
  545.         return;
  546.     }
  547.  
  548.     it = &itemlist[ent->client->pers.selected_item];
  549.     if (!it->use)
  550.     {
  551.         gi.cprintf (ent, PRINT_HIGH, "Item is not usable.\n");
  552.         return;
  553.     }
  554.     it->use (ent, it);
  555. }
  556.  
  557. //ZOID
  558. /*
  559. =================
  560. Cmd_LastWeap_f
  561. =================
  562. */
  563. void Cmd_LastWeap_f (edict_t *ent)
  564. {
  565.     gclient_t    *cl;
  566.  
  567.     cl = ent->client;
  568.  
  569.     if (!cl->pers.weapon || !cl->pers.lastweapon)
  570.         return;
  571.  
  572.     cl->pers.lastweapon->use (ent, cl->pers.lastweapon);
  573. }
  574. //ZOID
  575.  
  576. /*
  577. =================
  578. Cmd_WeapPrev_f
  579. =================
  580. */
  581. void Cmd_WeapPrev_f (edict_t *ent)
  582. {
  583.     gclient_t    *cl;
  584.     int            i, index;
  585.     gitem_t        *it;
  586.     int            selected_weapon;
  587.  
  588.     cl = ent->client;
  589.  
  590.     if (!cl->pers.weapon)
  591.         return;
  592.  
  593.     selected_weapon = ITEM_INDEX(cl->pers.weapon);
  594.  
  595.     // scan  for the next valid one
  596.     for (i=1 ; i<=MAX_ITEMS ; i++)
  597.     {
  598.         index = (selected_weapon + i)%MAX_ITEMS;
  599.         if (!cl->pers.inventory[index])
  600.             continue;
  601.         it = &itemlist[index];
  602.         if (!it->use)
  603.             continue;
  604.         if (! (it->flags & IT_WEAPON) )
  605.             continue;
  606.         it->use (ent, it);
  607.         if (cl->pers.weapon == it)
  608.             return;    // successful
  609.     }
  610. }
  611.  
  612. /*
  613. =================
  614. Cmd_WeapNext_f
  615. =================
  616. */
  617. void Cmd_WeapNext_f (edict_t *ent)
  618. {
  619.     gclient_t    *cl;
  620.     int            i, index;
  621.     gitem_t        *it;
  622.     int            selected_weapon;
  623.  
  624.     cl = ent->client;
  625.  
  626.     if (!cl->pers.weapon)
  627.         return;
  628.  
  629.     selected_weapon = ITEM_INDEX(cl->pers.weapon);
  630.  
  631.     // scan  for the next valid one
  632.     for (i=1 ; i<=MAX_ITEMS ; i++)
  633.     {
  634.         index = (selected_weapon + MAX_ITEMS - i)%MAX_ITEMS;
  635.         if (!cl->pers.inventory[index])
  636.             continue;
  637.         it = &itemlist[index];
  638.         if (!it->use)
  639.             continue;
  640.         if (! (it->flags & IT_WEAPON) )
  641.             continue;
  642.         it->use (ent, it);
  643.         if (cl->pers.weapon == it)
  644.             return;    // successful
  645.     }
  646. }
  647.  
  648. /*
  649. =================
  650. Cmd_WeapLast_f
  651. =================
  652. */
  653. void Cmd_WeapLast_f (edict_t *ent)
  654. {
  655.     gclient_t    *cl;
  656.     int            index;
  657.     gitem_t        *it;
  658.  
  659.     cl = ent->client;
  660.  
  661.     if (!cl->pers.weapon || !cl->pers.lastweapon)
  662.         return;
  663.  
  664.     index = ITEM_INDEX(cl->pers.lastweapon);
  665.     if (!cl->pers.inventory[index])
  666.         return;
  667.     it = &itemlist[index];
  668.     if (!it->use)
  669.         return;
  670.     if (! (it->flags & IT_WEAPON) )
  671.         return;
  672.     it->use (ent, it);
  673. }
  674.  
  675. /*
  676. =================
  677. Cmd_InvDrop_f
  678. =================
  679. */
  680. void Cmd_InvDrop_f (edict_t *ent)
  681. {
  682.     gitem_t        *it;
  683.  
  684.     ValidateSelectedItem (ent);
  685.  
  686.     if (ent->client->pers.selected_item == -1)
  687.     {
  688.         gi.cprintf (ent, PRINT_HIGH, "No item to drop.\n");
  689.         return;
  690.     }
  691.  
  692.     it = &itemlist[ent->client->pers.selected_item];
  693.     if (!it->drop)
  694.     {
  695.         gi.cprintf (ent, PRINT_HIGH, "Item is not dropable.\n");
  696.         return;
  697.     }
  698.     it->drop (ent, it);
  699. }
  700.  
  701. /*
  702. =================
  703. Cmd_Kill_f
  704. =================
  705. */
  706. void Cmd_Kill_f (edict_t *ent)
  707. {
  708. //ZOID
  709.     if (ent->solid == SOLID_NOT)
  710.         return;
  711. //ZOID
  712.  
  713.     if((level.time - ent->client->respawn_time) < 5)
  714.         return;
  715.     ent->flags &= ~FL_GODMODE;
  716.     ent->health = 0;
  717.     meansOfDeath = MOD_SUICIDE;
  718.     player_die (ent, ent, ent, 100000, vec3_origin);
  719. }
  720.  
  721. /*
  722. =================
  723. Cmd_PutAway_f
  724. =================
  725. */
  726. void Cmd_PutAway_f (edict_t *ent)
  727. {
  728.     ent->client->showscores = false;
  729.     ent->client->showhelp = false;
  730.     ent->client->showinventory = false;
  731. //ZOID
  732.     if (ent->client->menu)
  733.         PMenu_Close(ent);
  734.     ent->client->update_chase = true;
  735. //ZOID
  736. }
  737.  
  738.  
  739. int PlayerSort (void const *a, void const *b)
  740. {
  741.     int        anum, bnum;
  742.  
  743.     anum = *(int *)a;
  744.     bnum = *(int *)b;
  745.  
  746.     anum = game.clients[anum].ps.stats[STAT_FRAGS];
  747.     bnum = game.clients[bnum].ps.stats[STAT_FRAGS];
  748.  
  749.     if (anum < bnum)
  750.         return -1;
  751.     if (anum > bnum)
  752.         return 1;
  753.     return 0;
  754. }
  755.  
  756. /*
  757. =================
  758. Cmd_Players_f
  759. =================
  760. */
  761. void Cmd_Players_f (edict_t *ent)
  762. {
  763.     int        i;
  764.     int        count;
  765.     char    small[64];
  766.     char    large[1280];
  767.     int        index[256];
  768.  
  769.     count = 0;
  770.     for (i = 0 ; i < maxclients->value ; i++)
  771.         if (game.clients[i].pers.connected)
  772.         {
  773.             index[count] = i;
  774.             count++;
  775.         }
  776.  
  777.     // sort by frags
  778.     qsort (index, count, sizeof(index[0]), PlayerSort);
  779.  
  780.     // print information
  781.     large[0] = 0;
  782.  
  783.     for (i = 0 ; i < count ; i++)
  784.     {
  785.         Com_sprintf (small, sizeof(small), "%3i %s\n",
  786.             game.clients[index[i]].ps.stats[STAT_FRAGS],
  787.             game.clients[index[i]].pers.netname);
  788.         if (strlen (small) + strlen(large) > sizeof(large) - 100 )
  789.         {    // can't print all of them in one packet
  790.             strcat (large, "...\n");
  791.             break;
  792.         }
  793.         strcat (large, small);
  794.     }
  795.  
  796.     gi.cprintf (ent, PRINT_HIGH, "%s\n%i players\n", large, count);
  797. }
  798.  
  799. /*
  800. =================
  801. Cmd_Wave_f
  802. =================
  803. */
  804. void Cmd_Wave_f (edict_t *ent)
  805. {
  806.     int        i;
  807.  
  808.     i = atoi (gi.argv(1));
  809.  
  810.     // can't wave when ducked
  811.     if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
  812.         return;
  813.  
  814.     if (ent->client->anim_priority > ANIM_WAVE)
  815.         return;
  816.  
  817.     ent->client->anim_priority = ANIM_WAVE;
  818.  
  819.     switch (i)
  820.     {
  821.     case 0:
  822.         gi.cprintf (ent, PRINT_HIGH, "flipoff\n");
  823.         ent->s.frame = FRAME_flip01-1;
  824.         ent->client->anim_end = FRAME_flip12;
  825.         break;
  826.     case 1:
  827.         gi.cprintf (ent, PRINT_HIGH, "salute\n");
  828.         ent->s.frame = FRAME_salute01-1;
  829.         ent->client->anim_end = FRAME_salute11;
  830.         break;
  831.     case 2:
  832.         gi.cprintf (ent, PRINT_HIGH, "taunt\n");
  833.         ent->s.frame = FRAME_taunt01-1;
  834.         ent->client->anim_end = FRAME_taunt17;
  835.         break;
  836.     case 3:
  837.         gi.cprintf (ent, PRINT_HIGH, "wave\n");
  838.         ent->s.frame = FRAME_wave01-1;
  839.         ent->client->anim_end = FRAME_wave11;
  840.         break;
  841.     case 4:
  842.     default:
  843.         gi.cprintf (ent, PRINT_HIGH, "point\n");
  844.         ent->s.frame = FRAME_point01-1;
  845.         ent->client->anim_end = FRAME_point12;
  846.         break;
  847.     }
  848. }
  849.  
  850. qboolean CheckFlood(edict_t *ent)
  851. {
  852.     int        i;
  853.     gclient_t *cl;
  854.  
  855.     if (flood_msgs->value) {
  856.         cl = ent->client;
  857.  
  858.         if (level.time < cl->flood_locktill) {
  859.             gi.cprintf(ent, PRINT_HIGH, "You can't talk for %d more seconds\n",
  860.                 (int)(cl->flood_locktill - level.time));
  861.             return true;
  862.         }
  863.         i = cl->flood_whenhead - flood_msgs->value + 1;
  864.         if (i < 0)
  865.             i = (sizeof(cl->flood_when)/sizeof(cl->flood_when[0])) + i;
  866.         if (cl->flood_when[i] && 
  867.             level.time - cl->flood_when[i] < flood_persecond->value) {
  868.             cl->flood_locktill = level.time + flood_waitdelay->value;
  869.             gi.cprintf(ent, PRINT_CHAT, "Flood protection:  You can't talk for %d seconds.\n",
  870.                 (int)flood_waitdelay->value);
  871.             return true;
  872.         }
  873.         cl->flood_whenhead = (cl->flood_whenhead + 1) %
  874.             (sizeof(cl->flood_when)/sizeof(cl->flood_when[0]));
  875.         cl->flood_when[cl->flood_whenhead] = level.time;
  876.     }
  877.     return false;
  878. }
  879.  
  880. /*
  881. ==================
  882. Cmd_Say_f
  883. ==================
  884. */
  885. void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
  886. {
  887.     int        j;
  888.     edict_t    *other;
  889.     char    *p;
  890.     char    text[2048];
  891.  
  892.     if (gi.argc () < 2 && !arg0)
  893.         return;
  894.  
  895.     if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
  896.         team = false;
  897.  
  898.     if (team)
  899.         Com_sprintf (text, sizeof(text), "(%s): ", ent->client->pers.netname);
  900.     else
  901.         Com_sprintf (text, sizeof(text), "%s: ", ent->client->pers.netname);
  902.  
  903.     if (arg0)
  904.     {
  905.         strcat (text, gi.argv(0));
  906.         strcat (text, " ");
  907.         strcat (text, gi.args());
  908.     }
  909.     else
  910.     {
  911.         p = gi.args();
  912.  
  913.         if (*p == '"')
  914.         {
  915.             p++;
  916.             p[strlen(p)-1] = 0;
  917.         }
  918.         strcat(text, p);
  919.     }
  920.  
  921.     // don't let text be too long for malicious reasons
  922.     if (strlen(text) > 150)
  923.         text[150] = 0;
  924.  
  925.     strcat(text, "\n");
  926.  
  927.     if (CheckFlood(ent))
  928.         return;
  929.  
  930.     if (dedicated->value)
  931.         gi.cprintf(NULL, PRINT_CHAT, "%s", text);
  932.  
  933.     for (j = 1; j <= game.maxclients; j++)
  934.     {
  935.         other = &g_edicts[j];
  936.         if (!other->inuse)
  937.             continue;
  938.         if (!other->client)
  939.             continue;
  940.         if (team)
  941.         {
  942.             if (!OnSameTeam(ent, other))
  943.                 continue;
  944.         }
  945.         gi.cprintf(other, PRINT_CHAT, "%s", text);
  946.     }
  947. }
  948.  
  949. /*
  950. =================
  951. ClientCommand
  952. =================
  953. */
  954. void ClientCommand (edict_t *ent)
  955. {
  956.     char    *cmd;
  957.  
  958.     if (!ent->client)
  959.         return;        // not fully in game yet
  960.  
  961.     cmd = gi.argv(0);
  962.  
  963.     if (Q_stricmp (cmd, "players") == 0)
  964.     {
  965.         Cmd_Players_f (ent);
  966.         return;
  967.     }
  968.     if (Q_stricmp (cmd, "say") == 0)
  969.     {
  970.         Cmd_Say_f (ent, false, false);
  971.         return;
  972.     }
  973.     if (Q_stricmp (cmd, "say_team") == 0 || Q_stricmp (cmd, "steam") == 0)
  974.     {
  975.         CTFSay_Team(ent, gi.args());
  976.         return;
  977.     }
  978.     if (Q_stricmp (cmd, "score") == 0)
  979.     {
  980.         Cmd_Score_f (ent);
  981.         return;
  982.     }
  983.     if (Q_stricmp (cmd, "help") == 0)
  984.     {
  985.         Cmd_Help_f (ent);
  986.         return;
  987.     }
  988.  
  989.     if (level.intermissiontime)
  990.         return;
  991.  
  992.     if (Q_stricmp (cmd, "use") == 0)
  993.         Cmd_Use_f (ent);
  994.     else if (Q_stricmp (cmd, "drop") == 0)
  995.         Cmd_Drop_f (ent);
  996.     else if (Q_stricmp (cmd, "give") == 0)
  997.         Cmd_Give_f (ent);
  998.     else if (Q_stricmp (cmd, "god") == 0)
  999.         Cmd_God_f (ent);
  1000.     else if (Q_stricmp (cmd, "notarget") == 0)
  1001.         Cmd_Notarget_f (ent);
  1002.     else if (Q_stricmp (cmd, "noclip") == 0)
  1003.         Cmd_Noclip_f (ent);
  1004.     else if (Q_stricmp (cmd, "inven") == 0)
  1005.         Cmd_Inven_f (ent);
  1006.     else if (Q_stricmp (cmd, "invnext") == 0)
  1007.         SelectNextItem (ent, -1);
  1008.     else if (Q_stricmp (cmd, "invprev") == 0)
  1009.         SelectPrevItem (ent, -1);
  1010.     else if (Q_stricmp (cmd, "invnextw") == 0)
  1011.         SelectNextItem (ent, IT_WEAPON);
  1012.     else if (Q_stricmp (cmd, "invprevw") == 0)
  1013.         SelectPrevItem (ent, IT_WEAPON);
  1014.     else if (Q_stricmp (cmd, "invnextp") == 0)
  1015.         SelectNextItem (ent, IT_POWERUP);
  1016.     else if (Q_stricmp (cmd, "invprevp") == 0)
  1017.         SelectPrevItem (ent, IT_POWERUP);
  1018.     else if (Q_stricmp (cmd, "invuse") == 0)
  1019.         Cmd_InvUse_f (ent);
  1020.     else if (Q_stricmp (cmd, "invdrop") == 0)
  1021.         Cmd_InvDrop_f (ent);
  1022.     else if (Q_stricmp (cmd, "weapprev") == 0)
  1023.         Cmd_WeapPrev_f (ent);
  1024.     else if (Q_stricmp (cmd, "weapnext") == 0)
  1025.         Cmd_WeapNext_f (ent);
  1026.     else if (Q_stricmp (cmd, "weaplast") == 0)
  1027.         Cmd_WeapLast_f (ent);
  1028.     else if (Q_stricmp (cmd, "kill") == 0)
  1029.         Cmd_Kill_f (ent);
  1030.     else if (Q_stricmp (cmd, "putaway") == 0)
  1031.         Cmd_PutAway_f (ent);
  1032.     else if (Q_stricmp (cmd, "wave") == 0)
  1033.         Cmd_Wave_f (ent);
  1034. //ZOID
  1035.     else if (Q_stricmp (cmd, "team") == 0)
  1036.     {
  1037.         CTFTeam_f (ent);
  1038.     } else if (Q_stricmp(cmd, "id") == 0) {
  1039.         CTFID_f (ent);
  1040.     } else if (Q_stricmp(cmd, "yes") == 0) {
  1041.         CTFVoteYes(ent);
  1042.     } else if (Q_stricmp(cmd, "no") == 0) {
  1043.         CTFVoteNo(ent);
  1044.     } else if (Q_stricmp(cmd, "ready") == 0) {
  1045.         CTFReady(ent);
  1046.     } else if (Q_stricmp(cmd, "notready") == 0) {
  1047.         CTFNotReady(ent);
  1048.     } else if (Q_stricmp(cmd, "ghost") == 0) {
  1049.         CTFGhost(ent);
  1050.     } else if (Q_stricmp(cmd, "admin") == 0) {
  1051.         CTFAdmin(ent);
  1052.     } else if (Q_stricmp(cmd, "stats") == 0) {
  1053.         CTFStats(ent);
  1054.     } else if (Q_stricmp(cmd, "warp") == 0) {
  1055.         CTFWarp(ent);
  1056.     } else if (Q_stricmp(cmd, "boot") == 0) {
  1057.         CTFBoot(ent);
  1058.     } else if (Q_stricmp(cmd, "playerlist") == 0) {
  1059.         CTFPlayerList(ent);
  1060.     } else if (Q_stricmp(cmd, "observer") == 0) {
  1061.         CTFObserver(ent);
  1062.     }
  1063. //ZOID
  1064.     else    // anything that doesn't match a command will be a chat
  1065.         Cmd_Say_f (ent, false, true);
  1066. }
  1067.